#pragma once
#include"ThreadSafeQueue.h"
#include<atomic>
#include<functional>
#include<assert.h>
#include<thread>
#include"Logger.h"

using Task = std::function<void()>;

class WorkThread {
private:
	std::shared_ptr<ThreadSafeQueue<Task>> queue_;

	bool isRunning;   
	bool isPause;

	std::thread thread_;
	std::mutex mutex_;
	std::condition_variable cond_;

	const std::chrono::seconds maxSleepTime = std::chrono::seconds(30);


public:

	WorkThread(std::shared_ptr<ThreadSafeQueue<Task>> queue) :
		queue_(queue), isRunning(true), isPause(true), thread_(&WorkThread::threadFunc,this)
	{
	}

	WorkThread(std::shared_ptr<ThreadSafeQueue<Task>> queue, const std::chrono::seconds maxSleepTime) :
		queue_(queue), isRunning(true), isPause(true), 
		thread_(&WorkThread::threadFunc, this), maxSleepTime(maxSleepTime)
	{
	}

	~WorkThread() {
		if (thread_.joinable())
			thread_.join();
		Log::LOG_INFO << "~WorkThread  exit!";
	}


	void start() {
		std::unique_lock<std::mutex>lock(mutex_);
		isPause = false;
		cond_.notify_one();
	}

	void pause() {
		std::unique_lock<std::mutex>lock(mutex_);
		isPause = true;
	}

	void exit() {
		std::unique_lock<std::mutex>lock(mutex_);
		isRunning = false;
		cond_.notify_one();
	}

	void threadFunc() {
		Log::LOG_INFO << "WorkThread  start!" ;
		while (isRunning) {
			if(isPause){
				Log::LOG_INFO << "WorkThread  pause!";
				std::unique_lock<std::mutex>lock(mutex_);
				cond_.wait(lock, [this]() {return !isRunning || !isPause; });
				if (!isRunning)
					break;
				Log::LOG_INFO << "WorkThread  restart!";
			}
			Task task;
			if (queue_->waitAndPop(task, maxSleepTime)) {
				task();
			}
			else {
				Log::LOG_INFO << "WorkThread  timeout!";
			}
		}
		Log::LOG_INFO << "WorkThread  finish!";
	}

};

